#ifndef QTREEMODEL_H
#define QTREEMODEL_H

#include <QAbstractItemModel>

class QAbstractTreeNode;

/**
 * @brief The QAbstractTreeModel class
 */
class QAbstractTreeModel : public QAbstractItemModel
{
    Q_OBJECT
protected:
    /**
     * @brief rootNode
     */
    QAbstractTreeNode* rootNode;

public:
    /**
     * @brief QAbstractTreeModel
     * @param headers
     * @param parent
     */
    QAbstractTreeModel(const QStringList& headers, QObject* parent = 0);
    /**
     * @brief ~QAbstractTreeModel
     */
    virtual ~QAbstractTreeModel();
    /**
     * @brief data
     * @param index
     * @param role
     * @return
     */
    QVariant data(const QModelIndex &index, int role) const;
    /**
     * @brief headerData
     * @param section
     * @param orientation
     * @param role
     * @return
     */
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
    /**
     * @brief index
     * @param row
     * @param column
     * @param parent
     * @return
     */
    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
    /**
     * @brief parent
     * @param index
     * @return
     */
    QModelIndex parent(const QModelIndex &index) const;
    /**
     * @brief rowCount
     * @param parent
     * @return
     */
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    /**
     * @brief columnCount
     * @param parent
     * @return
     */
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    /**
     * @brief flags
     * @param index
     * @return
     */
    Qt::ItemFlags flags(const QModelIndex &index) const;
    /**
     * @brief setData
     * @param index
     * @param value
     * @param role
     * @return
     */
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
    /**
     * @brief setHeaderData
     * @param section
     * @param orientation
     * @param value
     * @param role
     * @return
     */
    bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
    /**
     * @brief insertColumns
     * @param position
     * @param columns
     * @param parent
     * @return
     */
    bool insertColumns(int position, int columns, const QModelIndex &parent = QModelIndex());
    /**
     * @brief removeColumns
     * @param position
     * @param columns
     * @param parent
     * @return
     */
    bool removeColumns(int position, int columns, const QModelIndex &parent = QModelIndex());
    /**
     * @brief insertRows
     * @param position
     * @param rows
     * @param parent
     * @return
     */
    bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex());
    /**
     * @brief removeRows
     * @param position
     * @param rows
     * @param parent
     * @return
     */
    bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex());
    /**
     * @brief getNode
     * @param index
     * @return
     */
    QAbstractTreeNode* getNode(const QModelIndex& index) const;

public slots:
    /**
     * @brief refreshData
     */
    void refreshData();
};

#endif // QTREEMODEL_H
